'use client';

import { useState, useEffect } from 'react';
import { Word, Category, PartOfSpeech, WordSense } from '@/types';
import ImportExportToolbar from './ImportExportToolbar';
import { downloadCsv, downloadXls, downloadXlsx, parseCsv, parseExcelXml, parseXlsx } from '@/lib/importExportUtils';

export default function WordManager() {
  const [words, setWords] = useState<Word[]>([]);
  const [allWords, setAllWords] = useState<Word[]>([]);
  const [categories, setCategories] = useState<Category[]>([]);
  const [posList, setPosList] = useState<PartOfSpeech[]>([]);
  const [selectedWord, setSelectedWord] = useState<Word | null>(null);
  const [showModal, setShowModal] = useState(false);
  const [formData, setFormData] = useState({ english: '', chinese: '', categoryIds: [] as string[] });
  const [selectedPath, setSelectedPath] = useState<string[]>([]);
  const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set());
  const [currentPage, setCurrentPage] = useState(1);
  const [pageSize] = useState(20);
  const [searchQuery, setSearchQuery] = useState({ english: '', chinese: '', definition: '' });
  const [showDetailModal, setShowDetailModal] = useState(false);
  const [detailWord, setDetailWord] = useState<Word | null>(null);
  const [showDeleteMenu, setShowDeleteMenu] = useState(false);
  const [showCategoryMenu, setShowCategoryMenu] = useState(false);
  const [showCategoryModal, setShowCategoryModal] = useState(false);
  const [categoryModalOp, setCategoryModalOp] = useState<'replace' | 'add' | 'remove' | null>(null);
  const [categoryModalIds, setCategoryModalIds] = useState<string[]>([]);
  const [categoryModalUniverse, setCategoryModalUniverse] = useState<string[]>([]);
  const [isApplyingCategories, setIsApplyingCategories] = useState(false);
  const [isImporting, setIsImporting] = useState(false);

  useEffect(() => {
    fetchWords();
    fetchCategories();
    fetchPos();
  }, []);

  const fetchWords = async () => {
    try {
      const res = await fetch('/api/words');
      const data = await res.json();
      if (data.success) {
        setAllWords(data.words);
        const selectedId = selectedPath.length ? selectedPath[selectedPath.length - 1] : '';
        applyFilter(data.words, selectedId);
      }
    } catch (error) {
      console.error(error);
    }
  };

  const fetchCategories = async () => {
    try {
      const res = await fetch('/api/categories');
      const data = await res.json();
      if (data.success) {
        setCategories(data.categories);
      }
    } catch (error) {
      console.error(error);
    }
  };

  const fetchPos = async () => {
    try {
      const res = await fetch('/api/pos');
      const data = await res.json();
      if (data.success) setPosList(data.items);
    } catch {}
  };


  const findCategoryById = (cats: Category[], id: string): Category | null => {
    for (const c of cats) {
      if (c.id === id) return c;
      if (c.children) {
        const found = findCategoryById(c.children, id);
        if (found) return found;
      }
    }
    return null;
  };

  const collectDescendantIds = (cat: Category | null): string[] => {
    if (!cat) return [];
    const ids: string[] = [cat.id];
    if (cat.children && cat.children.length) {
      for (const child of cat.children) {
        ids.push(...collectDescendantIds(child));
      }
    }
    return ids;
  };

  const applyFilter = (source: Word[], selectedCategoryId: string) => {
    let filtered = source;
    if (selectedCategoryId) {
      const sel = findCategoryById(categories, selectedCategoryId);
      const ids = new Set(collectDescendantIds(sel));
      filtered = filtered.filter(w => {
        const list = Array.isArray(w.categoryIds) && w.categoryIds.length ? w.categoryIds : (w.categoryId ? [w.categoryId] : []);
        return list.some(id => ids.has(id));
      });
    }
    // 应用搜索筛选
    if (searchQuery.english.trim()) {
      const q = searchQuery.english.trim().toLowerCase();
      filtered = filtered.filter(w => w.english.toLowerCase().includes(q));
    }
    if (searchQuery.chinese.trim()) {
      const q = searchQuery.chinese.trim().toLowerCase();
      filtered = filtered.filter(w => w.chinese.toLowerCase().includes(q));
    }
    if (searchQuery.definition.trim()) {
      const q = searchQuery.definition.trim().toLowerCase();
      filtered = filtered.filter(w => {
        if (!w.senses || w.senses.length === 0) return false;
        return w.senses.some(s => {
          const pos = posList.find(p => p.id === s.posId);
          const posName = pos ? `${pos.name}(${pos.key})` : '';
          const defs = s.definitions.join(' ');
          return (posName + ' ' + defs).toLowerCase().includes(q);
        });
      });
    }
    setWords(filtered);
    setCurrentPage(1);
  };

  useEffect(() => {
    const selectedId = selectedPath.length ? selectedPath[selectedPath.length - 1] : '';
    applyFilter(allWords, selectedId);
  }, [searchQuery, allWords, selectedPath, categories, posList]);

  useEffect(() => {
    const handleClickOutside = (e: MouseEvent) => {
      const target = e.target as HTMLElement;
      if (!target.closest('[data-menu-container]')) {
        setShowDeleteMenu(false);
        setShowCategoryMenu(false);
      }
    };
    if (showDeleteMenu || showCategoryMenu) {
      document.addEventListener('click', handleClickOutside);
      return () => document.removeEventListener('click', handleClickOutside);
    }
  }, [showDeleteMenu, showCategoryMenu]);

  const paginatedWords = words.slice((currentPage - 1) * pageSize, currentPage * pageSize);
  const totalPages = Math.ceil(words.length / pageSize);

  const getAllCategoriesFlat = (cats: Category[]): Category[] => {
    let result: Category[] = [];
    cats.forEach(cat => {
      result.push(cat);
      if (cat.children) {
        result = result.concat(getAllCategoriesFlat(cat.children));
      }
    });
    return result;
  };

  const getChildrenOf = (id?: string): Category[] => {
    if (!id) return categories;
    const parent = findCategoryById(categories, id);
    return parent?.children || [];
  };

  const handleCreate = () => {
    setSelectedWord(null);
    setFormData({ english: '', chinese: '', categoryIds: [] });
    setShowModal(true);
  };

  const handleEdit = (word: Word) => {
    setSelectedWord(word);
    const ids = Array.isArray(word.categoryIds) && word.categoryIds.length ? word.categoryIds : (word.categoryId ? [word.categoryId] : []);
    setFormData({ english: word.english, chinese: word.chinese, categoryIds: ids });
    setShowModal(true);
  };

  const handleDelete = async (id: string) => {
    if (!confirm('确定要删除这个单词吗？')) return;

    try {
      const res = await fetch(`/api/words/${id}`, { method: 'DELETE' });
      const data = await res.json();
      if (data.success) {
        fetchWords();
      } else {
        alert(data.message);
      }
    } catch (error) {
      alert('删除失败');
    }
  };

  const toggleSelectAll = (checked: boolean) => {
    if (checked) {
      const pageIds = new Set(paginatedWords.map(w => w.id));
      setSelectedIds(prev => {
        const next = new Set(prev);
        pageIds.forEach(id => next.add(id));
        return next;
      });
    } else {
      const pageIds = new Set(paginatedWords.map(w => w.id));
      setSelectedIds(prev => {
        const next = new Set(prev);
        pageIds.forEach(id => next.delete(id));
        return next;
      });
    }
  };

  const toggleSelectOne = (id: string, checked: boolean) => {
    setSelectedIds(prev => {
      const next = new Set(prev);
      if (checked) next.add(id); else next.delete(id);
      return next;
    });
  };

  const deleteSelected = async () => {
    if (selectedIds.size === 0) {
      alert('请先选择要删除的单词');
      return;
    }
    if (!confirm(`确认删除选中的 ${selectedIds.size} 个单词吗？`)) return;
    try {
      const res = await fetch('/api/words', {
        method: 'DELETE',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ ids: Array.from(selectedIds) }),
      });
      const data = await res.json();
      if (data.success) {
        await fetchWords();
        setSelectedIds(new Set());
      } else {
        alert(data.message || '删除失败');
      }
    } catch {
      alert('删除失败');
    }
  };

  const deleteAll = async () => {
    if (words.length === 0) {
      alert('没有可删除的单词');
      return;
    }
    if (!confirm(`警告：确认删除所有 ${words.length} 个单词吗？此操作不可恢复！`)) return;
    if (!confirm(`再次确认：真的要删除所有 ${words.length} 个单词吗？`)) return;
    try {
      const allIds = words.map(w => w.id);
      const res = await fetch('/api/words', {
        method: 'DELETE',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ ids: allIds }),
      });
      const data = await res.json();
      if (data.success) {
        await fetchWords();
        setSelectedIds(new Set());
        alert(`已删除所有 ${words.length} 个单词`);
      } else {
        alert(data.message || '删除失败');
      }
    } catch {
      alert('删除失败');
    }
  };


  const formatPosForExport = (senses?: WordSense[]): string => {
    if (!senses || senses.length === 0) return '';
    return senses.map(s => {
      const pos = posList.find(p => p.id === s.posId);
      return pos ? `${pos.name}(${pos.key})` : '';
    }).filter(Boolean).join(' | ');
  };

  const formatDefinitionsForExport = (senses?: WordSense[]): string => {
    if (!senses || senses.length === 0) return '';
    return senses.map(s => {
      const defs = s.definitions.filter(d => d.trim()).join('; ');
      return defs;
    }).filter(Boolean).join(' | ');
  };

  // Helper functions for single sense export (one row per part of speech)
  const formatPosForSingleSense = (sense: WordSense): string => {
    const pos = posList.find(p => p.id === sense.posId);
    return pos ? `${pos.name}(${pos.key})` : '';
  };

  const formatDefinitionsForSingleSense = (sense: WordSense): string => {
    return sense.definitions.filter(d => d.trim()).join('; ');
  };

  const formatSenses = (senses?: WordSense[]): string => {
    if (!senses || senses.length === 0) return '';
    return senses.map(s => {
      const pos = posList.find(p => p.id === s.posId);
      const posName = pos ? `${pos.name}(${pos.key})` : '';
      const defs = s.definitions.filter(d => d.trim()).join('; ');
      return `${posName}:${defs}`;
    }).join(' | ');
  };

  const formatSensesForList = (senses?: WordSense[]): string => {
    if (!senses || senses.length === 0) return '';
    const first = senses[0];
    const pos = posList.find(p => p.id === first.posId);
    const posName = pos ? `${pos.name}(${pos.key})` : '';
    const firstDef = first.definitions[0] || '';
    const result = `${posName}:${firstDef}`;
    if (senses.length > 1 || first.definitions.length > 1) {
      return result + '...';
    }
    return result;
  };

  const formatPosForList = (senses?: WordSense[]): string => {
    if (!senses || senses.length === 0) return '';
    const pos = posList.find(p => p.id === senses[0].posId);
    const posName = pos ? `${pos.name}(${pos.key})` : '';
    if (senses.length > 1) return posName + '...';
    return posName;
  };

  const formatDefinitionsForList = (senses?: WordSense[]): string => {
    if (!senses || senses.length === 0) return '';
    const firstDef = senses[0].definitions[0] || '';
    const hasMore = senses.length > 1 || senses[0].definitions.length > 1;
    return hasMore ? firstDef + '...' : firstDef;
  };

  const handleExportSelected = (format: 'csv' | 'xls' | 'xlsx') => {
    const selected = words.filter(w => selectedIds.has(w.id));
    if (selected.length === 0) return;
    const headers = ['ID', '英文', /* '音标', */ '中文', '分类', '词性', '释义'];
    const rows: (string | number)[][] = [];
    selected.forEach(w => {
      const categoryPath = getCategoryLabelForExport(w);
      if (!w.senses || w.senses.length === 0) {
        rows.push([w.id, w.english, w.chinese, categoryPath, '', '']);
      } else {
        w.senses.forEach(sense => {
          rows.push([
            w.id,
            w.english,
            w.chinese,
            categoryPath,
            formatPosForSingleSense(sense),
            formatDefinitionsForSingleSense(sense)
          ]);
        });
      }
    });
    const filename = `words_selected_${Date.now()}`;
    if (format === 'csv') {
      downloadCsv(`${filename}.csv`, headers, rows);
    } else if (format === 'xls') {
      downloadXls(`${filename}.xls`, headers, rows);
    } else {
      downloadXlsx(`${filename}.xlsx`, headers, rows);
    }
  };

  const handleExportAll = (format: 'csv' | 'xls' | 'xlsx') => {
    if (words.length === 0) return;
    const headers = ['ID', '英文', /* '音标', */ '中文', '分类', '词性', '释义'];
    const rows: (string | number)[][] = [];
    words.forEach(w => {
      const categoryPath = getCategoryLabelForExport(w);
      if (!w.senses || w.senses.length === 0) {
        rows.push([w.id, w.english, w.chinese, categoryPath, '', '']);
      } else {
        w.senses.forEach(sense => {
          rows.push([
            w.id,
            w.english,
            w.chinese,
            categoryPath,
            formatPosForSingleSense(sense),
            formatDefinitionsForSingleSense(sense)
          ]);
        });
      }
    });
    const filename = `words_all_${Date.now()}`;
    if (format === 'csv') {
      downloadCsv(`${filename}.csv`, headers, rows);
    } else if (format === 'xls') {
      downloadXls(`${filename}.xls`, headers, rows);
    } else {
      downloadXlsx(`${filename}.xlsx`, headers, rows);
    }
  };


  const handleDownloadTemplate = (format: 'csv' | 'xls' | 'xlsx') => {
    const headers = ['english', /* 'phonetic', */ 'chinese', 'categoryPath', 'senses'];
    const example = ['apple', /* '/æpl/', */ '苹果', 'Fruit', '名词(n):苹果; 动词(v):摘苹果'];
    if (format === 'csv') {
      downloadCsv('words_template.csv', headers, [example]);
    } else if (format === 'xls') {
      downloadXls('words_template.xls', headers, [example]);
    } else {
      downloadXlsx('words_template.xlsx', headers, [example]);
    }
  };

  const parseSenses = (sensesStr: string): WordSense[] => {
    if (!sensesStr || !sensesStr.trim()) return [];
    const result: WordSense[] = [];
    const parts = sensesStr.split('|').map(s => s.trim()).filter(Boolean);
    for (const part of parts) {
      const colonIdx = part.indexOf(':');
      if (colonIdx < 0) continue;
      const posPart = part.substring(0, colonIdx).trim();
      const defsPart = part.substring(colonIdx + 1).trim();
      if (!defsPart) continue;
      const posKeyMatch = posPart.match(/\(([^)]+)\)/);
      const posKey = posKeyMatch ? posKeyMatch[1] : posPart;
      const pos = posList.find(p => p.key === posKey || p.name === posPart);
      if (!pos) continue;
      const definitions = defsPart.split(';').map(d => d.trim()).filter(Boolean);
      if (definitions.length > 0) {
        result.push({ posId: pos.id, definitions });
      }
    }
    return result;
  };

  const handleImport = async (file: File, format: 'csv' | 'xls' | 'xlsx') => {
    if (isImporting) return;
    setIsImporting(true);
    try {
      let rows: string[][];
      if (format === 'csv') {
        const text = await file.text();
        rows = parseCsv(text);
      } else if (format === 'xls') {
        const text = await file.text();
        rows = parseExcelXml(text);
      } else {
        rows = await parseXlsx(file);
      }
      if (rows.length === 0) {
        alert(format === 'xls' ? 'Excel 为空或格式不受支持（请使用.xls XML工作簿或改用CSV）' : '文件为空');
        return;
      }
      const [h0, ...data] = rows;
      const header = h0.map(h => String(h).trim().toLowerCase());
      const idxEnglish = header.indexOf('english');
      const idxChinese = header.indexOf('chinese');
      const idxCatPath = header.indexOf('categorypath');
      const idxSenses = header.indexOf('senses');
      if (idxEnglish < 0) {
        alert(`缺少必要列：english\n当前列：${h0.join(', ')}`);
        return;
      }
      const allFlat = getAllCategoriesFlat(categories);
      let ok = 0, failed = 0;
      const errors: string[] = [];
      for (let i = 0; i < data.length; i++) {
        const r = data[i];
        const english = String(r[idxEnglish] || '').trim();
        if (!english) {
          failed++;
          errors.push(`第${i + 2}行：英文单词不能为空`);
          continue;
        }
        const chinese = idxChinese >= 0 ? String(r[idxChinese] || '').trim() : '';
        const categoryPath = idxCatPath >= 0 ? String(r[idxCatPath] || '').trim() : '';
        let categoryId: string | undefined = undefined;
        if (categoryPath) {
          const cat = allFlat.find(c => c.path === categoryPath);
          if (!cat) {
            failed++;
            errors.push(`第${i + 2}行：分类"${categoryPath}"不存在`);
            continue;
          }
          categoryId = cat.id;
        }
        const sensesStr = idxSenses >= 0 ? String(r[idxSenses] || '').trim() : '';
        const senses = sensesStr ? parseSenses(sensesStr) : undefined;
        const categoryIdsPayload = categoryId ? [categoryId] : undefined;
        try {
          const res = await fetch('/api/words', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ english, chinese: chinese || undefined, categoryIds: categoryIdsPayload, senses })
          });
          const dataJson = await res.json();
          if (dataJson.success) ok++;
          else {
            failed++;
            errors.push(`第${i + 2}行：${dataJson.message || '创建失败'}`);
          }
        } catch (e) {
          failed++;
          errors.push(`第${i + 2}行：网络错误`);
        }
      }
      await fetchWords();
      const msg = `导入完成：成功 ${ok} 条，失败 ${failed} 条${errors.length > 0 ? '\n\n前5个错误：\n' + errors.slice(0, 5).join('\n') : ''}`;
      alert(msg);
    } catch (e) {
      if (e instanceof Error && e.message.includes('xlsx')) {
        alert('请先安装 xlsx 库: npm install xlsx');
      } else {
        alert(`导入失败：${e instanceof Error ? e.message : '未知错误'}`);
      }
    } finally {
      setIsImporting(false);
    }
  };


  const [sensesDraft, setSensesDraft] = useState<WordSense[]>([]);

  const addSenseRow = () => {
    setSensesDraft(prev => [...prev, { posId: '', definitions: [''] }]);
  };
  const removeSenseRow = (idx: number) => {
    setSensesDraft(prev => prev.filter((_, i) => i !== idx));
  };
  const setSensePos = (idx: number, posId: string) => {
    setSensesDraft(prev => prev.map((s, i) => i === idx ? { ...s, posId } : s));
  };
  const setSenseDefinition = (idx: number, defIdx: number, val: string) => {
    setSensesDraft(prev => prev.map((s, i) => i === idx ? { ...s, definitions: s.definitions.map((d, j) => j === defIdx ? val : d) } : s));
  };
  const addDefinition = (idx: number) => {
    setSensesDraft(prev => prev.map((s, i) => i === idx ? { ...s, definitions: [...s.definitions, ''] } : s));
  };
  const removeDefinition = (idx: number, defIdx: number) => {
    setSensesDraft(prev => prev.map((s, i) => i === idx ? { ...s, definitions: s.definitions.filter((_, j) => j !== defIdx) } : s));
  };

  useEffect(() => {
    if (showModal) {
      if (selectedWord?.senses && selectedWord.senses.length) setSensesDraft(selectedWord.senses);
      else setSensesDraft([]);
    }
  }, [showModal, selectedWord]);

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    try {
      if (formData.categoryIds.length === 0) {
        alert('请至少选择一个分类');
        return;
      }
      if (selectedWord) {
        // 更新
        const res = await fetch(`/api/words/${selectedWord.id}`, {
          method: 'PUT',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ english: formData.english, chinese: formData.chinese, categoryIds: formData.categoryIds, senses: sensesDraft }),
        });
        const data = await res.json();
        if (data.success) {
          setShowModal(false);
          fetchWords();
        } else {
          alert(data.message);
        }
      } else {
        // 创建
        const res = await fetch('/api/words', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ english: formData.english, chinese: formData.chinese, categoryIds: formData.categoryIds, senses: sensesDraft }),
        });
        const data = await res.json();
        if (data.success) {
          setShowModal(false);
          fetchWords();
        } else {
          alert(data.message);
        }
      }
    } catch (error) {
      alert('操作失败');
    }
  };

  const allFlat = getAllCategoriesFlat(categories);
  const getCategoryPath = (categoryId: string) => {
    const cat = allFlat.find(c => c.id === categoryId);
    return cat ? cat.path : '未知分类';
  };
  const getCategoryDisplayForList = (w: Word) => {
    const ids = Array.isArray(w.categoryIds) && w.categoryIds.length ? w.categoryIds : (w.categoryId ? [w.categoryId] : []);
    if (ids.length === 0) return '未分类';
    const first = getCategoryPath(ids[0]);
    return ids.length > 1 ? first + '...' : first;
  };
  const getPrimaryCategoryId = (w: Word) => {
    const ids = Array.isArray(w.categoryIds) && w.categoryIds.length ? w.categoryIds : (w.categoryId ? [w.categoryId] : []);
    return ids[0] || '';
  };
  const getCategoryLabelForExport = (w: Word) => {
    const ids = Array.isArray(w.categoryIds) && w.categoryIds.length ? w.categoryIds : (w.categoryId ? [w.categoryId] : []);
    if (!ids.length) return '';
    return ids.map(id => getCategoryPath(id)).join(' | ');
  };

  const ensureSelection = () => {
    if (selectedIds.size === 0) {
      alert('请先勾选要操作的单词');
      return false;
    }
    return true;
  };

  const openCategoryOp = (op: 'replace' | 'add' | 'remove') => {
    if (!ensureSelection()) return;
    if (op === 'remove') {
      const idsUnion = new Set<string>();
      for (const w of words) {
        if (!selectedIds.has(w.id)) continue;
        const list = Array.isArray(w.categoryIds) && w.categoryIds.length ? w.categoryIds : (w.categoryId ? [w.categoryId] : []);
        list.forEach(id => idsUnion.add(id));
      }
      const defaultIds = Array.from(idsUnion);
      setCategoryModalIds(defaultIds);
      setCategoryModalOp(op);
      setShowCategoryModal(true);
      setShowCategoryMenu(false);
      setCategoryModalUniverse(defaultIds);
    } else {
      setCategoryModalIds([]);
      setCategoryModalOp(op);
      setShowCategoryModal(true);
      setShowCategoryMenu(false);
      setCategoryModalUniverse(allFlat.map(cat => cat.id));
    }
  };

  const applyBulkCategory = async (op: 'replace' | 'add' | 'remove' | 'clear', ids: string[] = []) => {
    if (!ensureSelection()) return;
    if ((op === 'replace' || op === 'add' || op === 'remove') && ids.length === 0) {
      alert('请至少选择一个分类');
      return;
    }
    try {
      setIsApplyingCategories(true);
      const res = await fetch('/api/words', {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ ids: Array.from(selectedIds), op, categoryIds: ids })
      });
      const data = await res.json();
      if (data.success) {
        setShowCategoryModal(false);
        setCategoryModalIds([]);
        setCategoryModalOp(null);
        await fetchWords();
        setCategoryModalUniverse([]);
      } else {
        alert(data.message || '分类操作失败');
      }
    } catch (error) {
      alert('分类操作失败');
    } finally {
      setIsApplyingCategories(false);
    }
  };

  return (
    <div>
      <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '20px', flexWrap: 'wrap', gap: '10px' }}>
        <h2>单词管理</h2>
        <div style={{ display: 'flex', gap: '10px' }}>
          <div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap' }}>
            {(() => {
              const selects: JSX.Element[] = [];
              let level = 0;
              let parentId: string | undefined = undefined;
              const maxLevels = 12;
              while (level < maxLevels) {
                const options = getChildrenOf(parentId);
                if (!options || options.length === 0) break;
                const value = selectedPath[level] || '';
                selects.push(
          <select
                    key={`cascade-${level}`}
            className="input"
                    value={value}
                    onChange={(e) => {
                      const val = e.target.value;
                      setSelectedPath(prev => {
                        const next = prev.slice(0, level);
                        if (val) next[level] = val;
                        return next;
                      });
                    }}
            style={{ width: '200px' }}
          >
                    <option value="">{level === 0 ? '全部分类' : '全部'}</option>
                    {options.map(opt => (
                      <option key={opt.id} value={opt.id}>{opt.name}</option>
            ))}
          </select>
                );
                if (!value) break;
                parentId = value;
                level += 1;
              }
              return selects;
            })()}
          </div>
          <button className="btn btn-primary" onClick={handleCreate}>
            添加单词
          </button>
        </div>
      </div>

      <div className="card">
        <div style={{ display: 'flex', gap: '10px', marginBottom: '10px', alignItems: 'center', flexWrap: 'wrap' }}>
          <div style={{ position: 'relative', display: 'inline-block' }} data-menu-container>
            <button className="btn btn-secondary" onClick={(e) => { e.stopPropagation(); setShowDeleteMenu(!showDeleteMenu); setShowCategoryMenu(false); }}>
              删除 {showDeleteMenu ? '▼' : '▶'}
            </button>
            {showDeleteMenu && (
              <div style={{ position: 'absolute', top: '100%', left: 0, backgroundColor: 'white', border: '1px solid #ddd', borderRadius: '4px', boxShadow: '0 2px 8px rgba(0,0,0,0.1)', zIndex: 1000, minWidth: '150px', marginTop: '4px' }}>
                <button className="btn" style={{ width: '100%', textAlign: 'left', padding: '8px', border: 'none', background: 'none', cursor: 'pointer', color: '#333', borderBottom: '1px solid #eee' }} onClick={() => { deleteSelected(); setShowDeleteMenu(false); }} disabled={selectedIds.size === 0}>
                  删除选中 ({selectedIds.size})
                </button>
                <button className="btn" style={{ width: '100%', textAlign: 'left', padding: '8px', border: 'none', background: 'none', cursor: 'pointer', color: '#dc3545', fontWeight: 'bold' }} onClick={() => { deleteAll(); setShowDeleteMenu(false); }} disabled={words.length === 0}>
                  删除全部 ({words.length})
                </button>
              </div>
            )}
          </div>
          <div style={{ position: 'relative', display: 'inline-block' }} data-menu-container>
            <button
              className="btn"
              disabled={selectedIds.size === 0}
              onClick={(e) => {
                e.stopPropagation();
                if (selectedIds.size === 0) return;
                setShowCategoryMenu(!showCategoryMenu);
                setShowDeleteMenu(false);
              }}
              title={selectedIds.size === 0 ? '请先勾选单词' : undefined}
            >
              分类操作 {showCategoryMenu ? '▼' : '▶'}
            </button>
            {showCategoryMenu && (
              <div style={{ position: 'absolute', top: '100%', left: 0, backgroundColor: 'white', border: '1px solid #ddd', borderRadius: '4px', boxShadow: '0 2px 8px rgba(0,0,0,0.1)', zIndex: 1000, minWidth: '180px', marginTop: '4px' }}>
                <button className="btn" style={{ width: '100%', textAlign: 'left', padding: '8px', border: 'none', background: 'none', cursor: 'pointer', borderBottom: '1px solid #eee' }} onClick={() => openCategoryOp('replace')} disabled={selectedIds.size === 0}>
                  替换分类
                </button>
                <button className="btn" style={{ width: '100%', textAlign: 'left', padding: '8px', border: 'none', background: 'none', cursor: 'pointer', borderBottom: '1px solid #eee' }} onClick={() => openCategoryOp('add')} disabled={selectedIds.size === 0}>
                  新增分类
                </button>
                <button className="btn" style={{ width: '100%', textAlign: 'left', padding: '8px', border: 'none', background: 'none', cursor: 'pointer', borderBottom: '1px solid #eee' }} onClick={() => openCategoryOp('remove')} disabled={selectedIds.size === 0}>
                  移除分类
                </button>
                <button className="btn" style={{ width: '100%', textAlign: 'left', padding: '8px', border: 'none', background: 'none', cursor: 'pointer', color: '#dc3545', fontWeight: 'bold' }} onClick={() => {
                  if (!ensureSelection()) return;
                  if (!confirm('确定要清空所选单词的所有分类吗？')) return;
                  setShowCategoryMenu(false);
                  applyBulkCategory('clear');
                }} disabled={selectedIds.size === 0}>
                  清空分类
                </button>
              </div>
            )}
          </div>
          <ImportExportToolbar
            onExportSelected={handleExportSelected}
            onExportAll={handleExportAll}
            onImport={handleImport}
            onDownloadTemplate={handleDownloadTemplate}
            isImporting={isImporting}
            selectedCount={selectedIds.size}
            totalCount={words.length}
          />
        </div>
        <div style={{ display: 'flex', gap: '10px', marginBottom: '10px', alignItems: 'center', flexWrap: 'wrap' }}>
          <input
            type="text"
            placeholder="搜索英文"
            value={searchQuery.english}
            onChange={(e) => setSearchQuery({ ...searchQuery, english: e.target.value })}
            style={{ padding: '8px', border: '1px solid #ddd', borderRadius: '4px', width: '150px' }}
          />
          <input
            type="text"
            placeholder="搜索中文"
            value={searchQuery.chinese}
            onChange={(e) => setSearchQuery({ ...searchQuery, chinese: e.target.value })}
            style={{ padding: '8px', border: '1px solid #ddd', borderRadius: '4px', width: '150px' }}
          />
          <input
            type="text"
            placeholder="搜索释义"
            value={searchQuery.definition}
            onChange={(e) => setSearchQuery({ ...searchQuery, definition: e.target.value })}
            style={{ padding: '8px', border: '1px solid #ddd', borderRadius: '4px', width: '150px' }}
          />
        </div>
        <div style={{ overflowX: 'auto' }}>
          <table style={{ width: '100%', borderCollapse: 'collapse' }}>
            <thead>
              <tr style={{ backgroundColor: '#f5f5f5' }}>
                <th style={{ padding: '10px', textAlign: 'left', borderBottom: '2px solid #ddd' }}>
                  <input type="checkbox" checked={paginatedWords.length>0 && paginatedWords.every(w => selectedIds.has(w.id))} onChange={e => toggleSelectAll(e.target.checked)} />
                </th>
                <th style={{ padding: '10px', textAlign: 'left', borderBottom: '2px solid #ddd' }}>英文</th>
                {/* <th style={{ padding: '10px', textAlign: 'left', borderBottom: '2px solid #ddd' }}>音标</th> */}
                <th style={{ padding: '10px', textAlign: 'left', borderBottom: '2px solid #ddd' }}>中文</th>
                <th style={{ padding: '10px', textAlign: 'left', borderBottom: '2px solid #ddd' }}>分类</th>
                <th style={{ padding: '10px', textAlign: 'left', borderBottom: '2px solid #ddd' }}>词性</th>
                <th style={{ padding: '10px', textAlign: 'left', borderBottom: '2px solid #ddd' }}>释义</th>
                <th style={{ padding: '10px', textAlign: 'left', borderBottom: '2px solid #ddd' }}>操作</th>
              </tr>
            </thead>
            <tbody>
              {paginatedWords.map(word => (
                <tr key={word.id} style={{ borderBottom: '1px solid #eee' }}>
                  <td style={{ padding: '10px' }}>
                    <input type="checkbox" checked={selectedIds.has(word.id)} onChange={e => toggleSelectOne(word.id, e.target.checked)} />
                  </td>
                  <td style={{ padding: '10px' }}>{word.english}</td>
                  {/* <td style={{ padding: '10px' }}>{word.phonetic || '-'}</td> */}
                  <td style={{ padding: '10px' }}>{word.chinese}</td>
                  <td style={{ padding: '10px' }}>{getCategoryDisplayForList(word)}</td>
                  <td style={{ padding: '10px' }}>{formatPosForList(word.senses)}</td>
                  <td style={{ padding: '10px' }}>{formatDefinitionsForList(word.senses)}</td>
                  <td style={{ padding: '10px' }}>
                    <button
                      className="btn"
                      style={{ padding: '5px 10px', marginRight: '5px', fontSize: '14px' }}
                      onClick={() => { setDetailWord(word); setShowDetailModal(true); }}
                    >
                      详情
                    </button>
                    <button
                      className="btn btn-secondary"
                      style={{ padding: '5px 10px', marginRight: '5px', fontSize: '14px' }}
                      onClick={() => handleEdit(word)}
                    >
                      编辑
                    </button>
                    <button
                      className="btn btn-danger"
                      style={{ padding: '5px 10px', fontSize: '14px' }}
                      onClick={() => handleDelete(word.id)}
                    >
                      删除
                    </button>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
          {words.length === 0 && <p style={{ padding: '20px', textAlign: 'center' }}>暂无单词</p>}
          {words.length > 0 && (
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '15px', borderTop: '1px solid #eee' }}>
              <div>
                共 {words.length} 条，第 {currentPage} / {totalPages} 页
              </div>
              <div style={{ display: 'flex', gap: '8px' }}>
                <button className="btn" onClick={() => setCurrentPage(1)} disabled={currentPage === 1}>首页</button>
                <button className="btn" onClick={() => setCurrentPage(p => Math.max(1, p - 1))} disabled={currentPage === 1}>上一页</button>
                <button className="btn" onClick={() => setCurrentPage(p => Math.min(totalPages, p + 1))} disabled={currentPage === totalPages}>下一页</button>
                <button className="btn" onClick={() => setCurrentPage(totalPages)} disabled={currentPage === totalPages}>末页</button>
              </div>
            </div>
          )}
        </div>
      </div>

      {showModal && (
        <div className="modal" onClick={() => setShowModal(false)}>
          <div className="modal-content" onClick={(e) => e.stopPropagation()}>
            <h2>{selectedWord ? '编辑单词' : '添加单词'}</h2>
            <form onSubmit={handleSubmit}>
              <div style={{ marginBottom: '15px' }}>
                <label style={{ display: 'block', marginBottom: '5px', fontWeight: 'bold' }}>
                  英文
                </label>
                <input
                  type="text"
                  className="input"
                  value={formData.english}
                  onChange={(e) => setFormData({ ...formData, english: e.target.value })}
                  required
                />
              </div>
              {/*
              <div style={{ marginBottom: '15px' }}>
                <label style={{ display: 'block', marginBottom: '5px', fontWeight: 'bold' }}>
                  音标
                </label>
                <input
                  type="text"
                  className="input"
                  value={formData.phonetic}
                  onChange={(e) => setFormData({ ...formData, phonetic: e.target.value })}
                  placeholder="例如: /æpl/"
                />
              </div>
              */}
              <div style={{ marginBottom: '15px' }}>
                <label style={{ display: 'block', marginBottom: '5px', fontWeight: 'bold' }}>
                  中文
                </label>
                <input
                  type="text"
                  className="input"
                  value={formData.chinese}
                  onChange={(e) => setFormData({ ...formData, chinese: e.target.value })}
                  required
                />
              </div>
              <div style={{ marginBottom: '15px' }}>
                <label style={{ display: 'block', marginBottom: '5px', fontWeight: 'bold' }}>分类（可多选）</label>
                <div style={{ maxHeight: '200px', overflow: 'auto', border: '1px solid #eee', borderRadius: 6, padding: 8 }}>
                  {allFlat.map(cat => {
                    const checked = formData.categoryIds.includes(cat.id);
                    return (
                      <label key={cat.id} style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '4px 0' }}>
                        <input
                          type="checkbox"
                          checked={checked}
                          onChange={(e) => {
                            setFormData(prev => {
                              const set = new Set(prev.categoryIds);
                              if (e.target.checked) set.add(cat.id); else set.delete(cat.id);
                              return { ...prev, categoryIds: Array.from(set) };
                            });
                          }}
                        />
                        <span>{cat.path}</span>
                </label>
                    );
                  })}
                </div>
              </div>
              <div style={{ marginBottom: '15px' }}>
                <label style={{ display: 'block', marginBottom: '5px', fontWeight: 'bold' }}>词性与释义</label>
                <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
                  {sensesDraft.map((s, i) => (
                    <div key={i} style={{ border: '1px solid #eee', borderRadius: 6, padding: 10 }}>
                      <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 8 }}>
                        <select className="input" value={s.posId} onChange={e => setSensePos(i, e.target.value)} style={{ width: 200 }}>
                          <option value="">选择词性</option>
                          {posList.map(p => (
                            <option key={p.id} value={p.id}>{p.name} ({p.key})</option>
                          ))}
                        </select>
                        <button type="button" className="btn btn-danger" onClick={() => removeSenseRow(i)}>删除词性</button>
                      </div>
                      <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                        {s.definitions.map((d, j) => (
                          <div key={j} style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
                            <input className="input" placeholder={`释义 ${j + 1}`} value={d} onChange={e => setSenseDefinition(i, j, e.target.value)} />
                            <button type="button" className="btn btn-secondary" onClick={() => removeDefinition(i, j)}>删除</button>
                          </div>
                        ))}
                        <button type="button" className="btn" onClick={() => addDefinition(i)}>新增释义</button>
                      </div>
                    </div>
                  ))}
                  <button type="button" className="btn" onClick={addSenseRow}>新增词性</button>
                </div>
              </div>
              <div style={{ display: 'flex', gap: '10px' }}>
                <button type="submit" className="btn btn-primary">
                  {selectedWord ? '更新' : '创建'}
                </button>
                <button
                  type="button"
                  className="btn btn-secondary"
                  onClick={() => setShowModal(false)}
                >
                  取消
                </button>
              </div>
            </form>
          </div>
        </div>
      )}

      {showDetailModal && detailWord && (
        <div className="modal" onClick={() => { setShowDetailModal(false); setDetailWord(null); }}>
          <div className="modal-content" onClick={(e) => e.stopPropagation()} style={{ maxWidth: '600px', maxHeight: '80vh', overflow: 'auto' }}>
            <h2>单词详情</h2>
            <div style={{ marginBottom: '15px' }}>
              <div style={{ marginBottom: '10px' }}>
                <strong>ID:</strong> {detailWord.id}
              </div>
              <div style={{ marginBottom: '10px' }}>
                <strong>英文:</strong> {detailWord.english}
              </div>
              {/*
              <div style={{ marginBottom: '10px' }}>
                <strong>音标:</strong> {detailWord.phonetic || '-'}
              </div>
              */}
              <div style={{ marginBottom: '10px' }}>
                <strong>中文:</strong> {detailWord.chinese}
              </div>
              <div style={{ marginBottom: '10px' }}>
                <strong>分类:</strong> {(() => {
                  const ids = Array.isArray(detailWord.categoryIds) && detailWord.categoryIds.length ? detailWord.categoryIds : (detailWord.categoryId ? [detailWord.categoryId] : []);
                  if (!ids.length) return '未分类';
                  return ids.map(id => getCategoryPath(id)).join(' | ');
                })()}
              </div>
              <div style={{ marginBottom: '10px' }}>
                <strong>创建时间:</strong> {new Date(detailWord.createdAt).toLocaleString('zh-CN')}
              </div>
              {detailWord.senses && detailWord.senses.length > 0 && (
                <div style={{ marginBottom: '10px' }}>
                  <strong>词性与释义:</strong>
                  <div style={{ marginTop: '8px', padding: '10px', backgroundColor: '#f5f5f5', borderRadius: '4px' }}>
                    {detailWord.senses.map((s, i) => {
                      const pos = posList.find(p => p.id === s.posId);
                      const posName = pos ? `${pos.name}(${pos.key})` : '未知词性';
                      return (
                        <div key={i} style={{ marginBottom: '8px', paddingBottom: '8px', borderBottom: i < detailWord.senses!.length - 1 ? '1px solid #ddd' : 'none' }}>
                          <div style={{ fontWeight: 'bold', marginBottom: '4px' }}>{posName}</div>
                          <div style={{ paddingLeft: '16px' }}>
                            {s.definitions.map((d, j) => (
                              <div key={j} style={{ marginBottom: '4px' }}>{j + 1}. {d}</div>
                            ))}
                          </div>
                        </div>
                      );
                    })}
                  </div>
                </div>
              )}
            </div>
            <div style={{ display: 'flex', gap: '10px' }}>
              <button
                type="button"
                className="btn btn-secondary"
                onClick={() => { setShowDetailModal(false); setDetailWord(null); }}
              >
                关闭
              </button>
              <button
                type="button"
                className="btn btn-primary"
                onClick={() => {
                  setShowDetailModal(false);
                  handleEdit(detailWord);
                }}
              >
                编辑
              </button>
            </div>
          </div>
        </div>
      )}

      {showCategoryModal && categoryModalOp && (
        <div className="modal" onClick={() => { if (!isApplyingCategories) { setShowCategoryModal(false); setCategoryModalOp(null); setCategoryModalIds([]); setCategoryModalUniverse([]); } }}>
          <div className="modal-content" onClick={(e) => e.stopPropagation()} style={{ maxWidth: '460px', width: '100%' }}>
            <h3 style={{ marginBottom: '16px' }}>
              {categoryModalOp === 'replace' && '替换为以下分类'}
              {categoryModalOp === 'add' && '为所选单词新增以下分类'}
              {categoryModalOp === 'remove' && '从所选单词移除以下分类'}
            </h3>
            <div style={{ maxHeight: '260px', overflow: 'auto', border: '1px solid #eee', borderRadius: 6, padding: 10, marginBottom: '20px' }}>
              {allFlat.filter(cat => categoryModalUniverse.length === 0 || categoryModalUniverse.includes(cat.id)).map(cat => {
                const checked = categoryModalIds.includes(cat.id);
                return (
                  <label key={cat.id} style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '4px 0' }}>
                    <input
                      type="checkbox"
                      checked={checked}
                      onChange={(e) => {
                        setCategoryModalIds(prev => {
                          const set = new Set(prev);
                          if (e.target.checked) set.add(cat.id); else set.delete(cat.id);
                          return Array.from(set);
                        });
                      }}
                    />
                    <span>{cat.path}</span>
                  </label>
                );
              })}
              {allFlat.length === 0 && <div>暂无分类</div>}
            </div>
            <div style={{ display: 'flex', gap: '10px' }}>
              <button
                className="btn btn-primary"
                onClick={() => categoryModalOp && applyBulkCategory(categoryModalOp, categoryModalIds)}
                disabled={isApplyingCategories}
              >
                {isApplyingCategories ? '处理中...' : '确定'}
              </button>
              <button
                className="btn btn-secondary"
                onClick={() => { if (!isApplyingCategories) { setShowCategoryModal(false); setCategoryModalOp(null); setCategoryModalIds([]); setCategoryModalUniverse([]); } }}
                disabled={isApplyingCategories}
              >
                取消
              </button>
            </div>
          </div>
        </div>
      )}

      {isImporting && (
        <div
          style={{
            position: 'fixed',
            top: 0,
            left: 0,
            width: '100%',
            height: '100%',
            backgroundColor: 'rgba(255, 255, 255, 0.7)',
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            zIndex: 2000,
            pointerEvents: 'auto',
            cursor: 'wait',
          }}
        >
          <div style={{ padding: '24px 32px', backgroundColor: '#fff', borderRadius: '8px', boxShadow: '0 4px 12px rgba(0,0,0,0.15)', fontSize: '16px', color: '#333' }}>
            正在导入文件，请稍候...
          </div>
        </div>
      )}
    </div>
  );
}

